package com.ruoyi.web.controller.finance;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.web.common.BusinessException;
import com.ruoyi.web.common.TypeNameEnum;
import com.ruoyi.web.dto.*;
import com.ruoyi.web.entity.*;
import com.ruoyi.web.mapper.BalanceChangeDetailMapper;
import com.ruoyi.web.service.AccountInfoService;
import com.ruoyi.web.service.AssetService;
import com.ruoyi.web.service.UserBalanceService;
import com.ruoyi.web.util.BigDecimalCheckUtils;
import com.ruoyi.web.util.LocalDateTimeUtils;
import com.ruoyi.web.util.OptionalUtils;
import com.ruoyi.web.util.PageUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 资产交易
 */
@Controller
@RequestMapping("/finance/zcjy")
public class ZcjyController {

    @Resource
    private UserBalanceService userBalanceService;
    @Resource
    private AccountInfoService accountInfoService;
    @Resource
    private BalanceChangeDetailMapper balanceChangeDetailMapper;
    @Resource
    private AssetService assetService;

    @GetMapping()
    public String user(Model modelAndView) {
//        List<FundAsset> allAsset = assetService.getAllAsset();
//        List<String> assetNameList = allAsset
//                .stream()
//                .map(FundAsset::getAssetName)
//                .collect(Collectors.toList());
//        modelAndView.addAttribute("allAssetNameList", assetNameList);
//
//
//        List<NowAssetPrice> holdAssetPriceList = allAsset.stream()
//                .filter(fundAsset -> !BigDecimalCheckUtils.isZero(fundAsset.getNumberOf()))
//                .sorted(Comparator.comparing(FundAsset::getTypeName)
//                        .thenComparing(FundAsset::getAssetName))
//                .map(fundAsset -> {
//                    AssetPrice assetPrice = assetService.fetchPrice(fundAsset);
//
//                    NowAssetPrice nowAssetPrice = new NowAssetPrice();
//                    nowAssetPrice.setTypeName(fundAsset.getTypeName());
//                    nowAssetPrice.setAssetName(fundAsset.getAssetName());
//                    if(assetPrice!=null){
//                        nowAssetPrice.setStartDate(LocalDateTimeUtils.dateTime2DateString(assetPrice.getStartDate()));
//                        nowAssetPrice.setPrice(assetPrice.getPrice().toPlainString());
//                    }
//
//                    return nowAssetPrice;
//                }).collect(Collectors.toList());
//        modelAndView.addAttribute("assetPriceList", holdAssetPriceList);
//


        /* 展示理财账户明细*/
        AccountInfo accountInfo = accountInfoService.getCurrentAccount();

        LocalDate dataDate = accountInfo.getDataDate();

        AccountDetailResp accountDetailResp = new AccountDetailResp();
        accountDetailResp.setDataDate(LocalDateTimeUtils.dateTime2DateString(dataDate));
        ArrayList<AccountDetailResp.AssetDetailResp> accountDetailList = Lists.newArrayList();
        accountDetailResp.setAssetDetailList(accountDetailList);

        for (TypeNameEnum typeNameEnum : TypeNameEnum.values()) {
            // 这里计算每个股票的明细信息
            accountDetailList.addAll(assetService.calcAssetDetail(dataDate, typeNameEnum.getTypeName()));
        }


        AccountDetailResp.AssetDetailResp e = new AccountDetailResp.AssetDetailResp();
        e.setTypeName("流动资金");
        e.setMarketValue(accountInfo.getLiquidity().toPlainString());
        accountDetailList.add(e);

        AccountDetailResp.AssetDetailResp zsj = new AccountDetailResp.AssetDetailResp();
        zsj.setTypeName("总市值");
        zsj.setMarketValue(OptionalUtils.sum(accountDetailList, assetSummaryResp -> new BigDecimal(assetSummaryResp.getMarketValue()))
                .toPlainString());
        // 当前总收益
        zsj.setCurrentEarnings(
                OptionalUtils.sum(
                                accountDetailList,
                                assetSummaryResp -> {
                                    if (NumberUtils.isCreatable(assetSummaryResp.getCurrentEarnings())) {
                                        return new BigDecimal(assetSummaryResp.getCurrentEarnings());
                                    } else {
                                        return BigDecimal.ZERO;
                                    }
                                })
                        .toPlainString());
        // 当前总历史收益
        zsj.setHistoryEarnings(
                OptionalUtils.sum(
                                accountDetailList,
                                assetSummaryResp -> {
                                    if (NumberUtils.isCreatable(assetSummaryResp.getHistoryEarnings())) {
                                        return new BigDecimal(assetSummaryResp.getHistoryEarnings());
                                    } else {
                                        return BigDecimal.ZERO;
                                    }
                                })
                        .toPlainString());
        accountDetailList.add(zsj);

        modelAndView.addAttribute("assetDetail", accountDetailResp);

        return "finance/zcjy/zcjy";
    }


    @GetMapping("/buyAsset")
    public String buyAsset(Model modelAndView) {
        List<FundAsset> allAsset = assetService.getAllAsset();
        List<String> assetNameList = allAsset
                .stream()
                .map(FundAsset::getAssetName)
                .collect(Collectors.toList());
        modelAndView.addAttribute("allAssetNameList", assetNameList);

        return "finance/zcjy/buyAsset";
    }

    /**
     * 买入资产
     */
    @PostMapping("/buyAssetOpt")
    @ResponseBody
    public AjaxResult buyAssetOpt(BuyAssetReq buyAssetReq) {
        try {
            boolean canFindAssetCode = false;
            int type = 0;
            if (StringUtils.isNotBlank(buyAssetReq.getAssetName())) {
                canFindAssetCode = true;
                type = 1;
            } else if (!StringUtils.isAnyBlank(buyAssetReq.getTypeName(), buyAssetReq.getNewAssetName())) {
                canFindAssetCode = true;
                type = 2;
            }
            if (!canFindAssetCode) {
                throw new BusinessException("请检查资产信息");
            }

            BigDecimalCheckUtils.isNumberAndGeZero("份额", buyAssetReq.getNumberOf(), 4);
            BigDecimalCheckUtils.isNumberAndGeZero("交易金额", buyAssetReq.getAmount(), 2);

            if (1 == type) {
                assetService.buyAsset(buyAssetReq);
            } else {
                assetService.buyNewAsset(buyAssetReq);
            }
            return AjaxResult.success();
        } catch (BusinessException e) {
            return AjaxResult.error(e.getMsg());
        }
    }


    @GetMapping("/saleAsset")
    public String saleAsset(Model modelAndView) {
        List<FundAsset> allAsset = assetService.getAllAsset();

        List<String> holdAssetNameList = allAsset
                .stream()
                .filter(fundAsset -> !BigDecimalCheckUtils.isZero(fundAsset.getNumberOf()))
                .map(FundAsset::getAssetName)
                .collect(Collectors.toList());
        modelAndView.addAttribute("holdAssetNameList", holdAssetNameList);

        return "finance/zcjy/saleAsset";
    }

    @GetMapping("/updatePrice")
    public String updatePrice(Model modelAndView) {
        List<FundAsset> allAsset = assetService.getAllAsset();

        List<String> holdAssetNameList = allAsset
                .stream()
                .filter(fundAsset -> !BigDecimalCheckUtils.isZero(fundAsset.getNumberOf()))
                .map(FundAsset::getAssetName)
                .collect(Collectors.toList());
        modelAndView.addAttribute("holdAssetNameList", holdAssetNameList);

        return "finance/zcjy/updatePrice";
    }

    /**
     * 卖出资产
     */
    @PostMapping("/saleAssetOpt")
    @ResponseBody
    public AjaxResult saleAssetOpt(BuyAssetReq buyAssetReq) {
        try {
            if (StringUtils.isBlank(buyAssetReq.getAssetName())) {
                throw new BusinessException("请检查资产信息");
            }

            BigDecimalCheckUtils.isNumberAndGeZero("份额", buyAssetReq.getAmount(), 4);
            BigDecimalCheckUtils.isNumberAndGeZero("金额", buyAssetReq.getAmount(), 2);

            assetService.saleAsset(buyAssetReq);
            return AjaxResult.success();
        } catch (BusinessException e) {
            return AjaxResult.error(e.getMsg());
        }
    }

    /**
     * 卖出资产
     */
    @PostMapping("/updatePrice")
    @ResponseBody
    public AjaxResult updatePrice(BuyAssetReq buyAssetReq) {
        try {
            if (StringUtils.isBlank(buyAssetReq.getAssetName())) {
                throw new BusinessException("请检查资产信息");
            }
            BigDecimalCheckUtils.isNumberAndGeZero("金额", buyAssetReq.getAmount(), 2);


            FundAsset one = assetService.lambdaQuery()
                    .eq(FundAsset::getAssetName, buyAssetReq.getAssetName())
                    .last("limit 0,1")
                    .one();

            LocalDate today = LocalDate.now();

            assetService.updateAssetPrice(today,one.getTypeName(),one.getAssetName(),new BigDecimal(buyAssetReq.getAmount()));
            return AjaxResult.success();
        } catch (BusinessException e) {
            return AjaxResult.error(e.getMsg());
        }
    }
}
